//
//  DClockSlider.swift
//  Drop
//
//  Created by hushaohua on 2018/10/22.
//  Copyright © 2018年 init. All rights reserved.
//

import UIKit


class DClockSlider: UIView, UIGestureRecognizerDelegate {

    var is60MarkLine:Bool = true;//是否是60个刻度
    var isMarkNumber:Bool = true; //是否标刻数字
    var trackLineWidth:CGFloat = 10;
    
    // Only override draw() if you perform custom drawing.
    // An empty implementation adversely affects performance during animation.
    
    lazy var trackLayer:CAShapeLayer = {
        var layer:CAShapeLayer = CAShapeLayer();
        return layer;
    }();
    lazy var thumbLayer:CALayer = {
        var layer = CALayer();
        layer.backgroundColor = UIColor.white.cgColor;
        return layer;
    }();
    func getProgressLayer(_ index:Int) -> CAShapeLayer{
        let layer:CAShapeLayer = CAShapeLayer();
        let offset = self.trackLineWidth * CGFloat(index + 1);
        let frame = CGRect(x: offset, y: offset, width: (self.bounds.size.width - 2 * offset), height: (self.bounds.size.height - 2 * offset));
        layer.fillColor = self.backgroundColor?.cgColor;
        layer.path = UIBezierPath(ovalIn: frame).cgPath;
        layer.strokeColor = UIColor.blue.cgColor;
        layer.lineWidth = 1;
        layer.strokeEnd = 0;
        self.layer.addSublayer(layer);
        return layer;
    }
    func getNextProgressLayer()  -> CAShapeLayer {
        self.progressIndex += 1;
        let layer = self.getProgressLayer(self.progressIndex);
        self.progressLayers.append(layer);
        self.layer.insertSublayer(layer, below: self.thumbLayer);
        return layer;
    }
    
    var progressIndex:Int = -1;
    lazy var progressLayers:[CAShapeLayer] = {
        var layers:[CAShapeLayer] = [CAShapeLayer]();
        return layers;
    }();
    func currentProgressLayer() -> CAShapeLayer {
        if (self.progressIndex < 0){
            return self.getNextProgressLayer();
        }else{
            return self.progressLayers[self.progressIndex];
        }
    }
    
    func addTrackLayer(){
        let halfLineWidth = self.trackLineWidth / 2;
        let frame = CGRect(x: halfLineWidth, y: halfLineWidth, width: (self.bounds.size.width - self.trackLineWidth), height: (self.bounds.size.height - self.trackLineWidth));
        self.trackLayer.fillColor = self.backgroundColor?.cgColor;
        self.trackLayer.path = UIBezierPath(ovalIn: frame).cgPath;
        self.trackLayer.strokeColor = UIColor.yellow.cgColor;
        self.trackLayer.lineWidth = self.trackLineWidth;
        self.layer.addSublayer(self.trackLayer);
    }
    func addThumbLayer() {
        let radius = 2 * self.trackLineWidth;
        self.thumbLayer.frame = CGRect(x: (self.bounds.size.width - radius), y: (self.bounds.size.height / 2 - self.trackLineWidth), width: radius, height: radius);
        self.thumbLayer.cornerRadius = self.trackLineWidth;
        self.thumbLayer.masksToBounds = true;
        self.thumbLayer.shadowRadius = self.trackLineWidth;
        self.thumbLayer.shadowColor = UIColor.lightGray.cgColor;
        self.thumbLayer.shadowOffset = CGSize(width: -2, height: 2);
        self.thumbLayer.shadowOpacity = 0.5;
        self.layer.addSublayer(self.thumbLayer);
    }
    
    override init(frame: CGRect) {
        super.init(frame: frame);
        
        self.addTrackLayer();
        self.addProgressGestures();
        self.addThumbLayer();
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    func addProgressGestures() {
        let pan:UIPanGestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(panRecognized(_:)));
        pan.delegate = self;
        self.isUserInteractionEnabled = true;
        self.addGestureRecognizer(pan);
    }
    
    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
        let point = touch.location(in: self);
        return self.thumbLayer.frame.contains(point);
    }
    
    var lastCheckValue:(valid:Bool, angle:CGFloat, percent:CGFloat)?;
    func checkPointPanGesture(_ point:CGPoint) -> (valid:Bool, angle:CGFloat, percent:CGFloat){
        let center = CGPoint(x: self.bounds.size.width / 2, y: self.bounds.size.height / 2);
        let xSize = point.x - center.x;
        let ySize = point.y - center.y;
        
        let maxValue = min(self.bounds.size.width, self.bounds.size.height) / 2;
        let minValue = maxValue / 2;
        let value = CGFloat(sqrtf(Float(xSize * xSize + ySize * ySize)));
        if (value >= minValue && value <= maxValue){
            let ap = self.anglePercent(xSize: xSize, ySize: ySize);
            return (true, ap.angle, ap.percent);
        }
        return (false, 0, 0);
    }
    
    func anglePercent(xSize:CGFloat, ySize:CGFloat) -> (angle:CGFloat, percent:CGFloat){
        let tanValue = atanf(Float(ySize / xSize));
        var angle:Double = 0;
        var percent:CGFloat = 0;
        if (xSize == 0 || ySize == 0){
            if xSize == 0 {
                if (ySize > 0){
                    angle = Double.pi / 2;
                    percent = 0.25;
                }else{
                    angle = Double.pi / 2 * 3;
                    percent = 0.75;
                }
            }else if ySize == 0 {
                if (xSize > 0){
                    if (self.lastCheckValue != nil && self.lastCheckValue!.angle > CGFloat(Double.pi)){
                        angle = Double.pi * 2;
                        percent = 1;
                    }else{
                        angle = 0;
                        percent = 0;
                    }
                }else{
                    angle = Double.pi;
                    percent = 0.5;
                }
            }
        }else{
            if xSize > 0 && ySize > 0 { //bottom right
                angle = Double(tanValue);
            }else if ySize > 0 { //bottom left
                angle = Double.pi + Double(tanValue);
            }else if xSize > 0 { //top right
                angle = 2 * Double.pi + Double(tanValue);
            }else{ // top left
                angle = Double.pi + Double(tanValue);
            }
            percent = CGFloat(angle / (2 * Double.pi));
            if (self.lastCheckValue != nil && self.lastCheckValue!.percent >= 0.9 && percent <= 0.1){
                percent = 1;
                angle = Double.pi * 2;
            }
        }
        
        return (CGFloat(angle), percent);
    }
    
    @objc func panRecognized(_ gesture:UIGestureRecognizer) {
        if gesture.state == .cancelled{
            return;
        }
        let location = gesture.location(in: self);
        let value = self.checkPointPanGesture(location);
        var thumbFrame = self.thumbLayer.frame;
        if (value.valid){
            self.lastCheckValue = value;
            let center = CGPoint(x: self.bounds.size.width / 2, y: self.bounds.size.height / 2);
            let radius = self.trackLineWidth;
            let xSize = (self.bounds.size.width / 2 - radius);
            thumbFrame.origin.x = center.x + xSize * cos(value.angle) - thumbFrame.size.width / 2;
            thumbFrame.origin.y = center.y + xSize * sin(value.angle) - thumbFrame.size.height / 2;
            self.thumbLayer.frame = thumbFrame;
            self.currentProgressLayer().strokeEnd = value.percent;
            if (value.percent >= 1) {
                _ = self.getNextProgressLayer();
                self.lastCheckValue = nil;
            }
        }
    }
}
